package android.slc.box.core.launcher;

import android.slc.box.core.controller.EventPlusHandler;
import android.slc.box.core.scope.StageScope;
import android.slc.box.core.utils.WindowUtils;
import android.slc.box.core.virtual_android.Bundle;
import cn.hutool.core.util.ArrayUtil;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.Scope;
import de.saxsys.mvvmfx.ViewModel;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import java.util.List;

public class StageLauncherImpl extends WindowLauncherImpl<Stage> implements StageLauncher {
    private StageScope stageScope;

    public StageLauncherImpl(StageScope stageScope, List<String> stylesheets, Bundle bundle) {
        this(stageScope.getCurrentStage(), stylesheets, bundle);
        this.stageScope = stageScope;
    }

    public StageLauncherImpl(Stage currentStage, List<String> stylesheets, Bundle bundle) {
        super(currentStage, stylesheets, bundle);
    }

    private void applyStyle(Scene scene) {
        if (getStylesheets() != null) {
            scene.getStylesheets().addAll(getStylesheets());
        }
    }

    @Override
    public void switchScene(Scene scene) {
        applyStyle(scene);
        requireWindow().setScene(scene);
    }

    @Override
    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> void switchView(Class<ViewType> viewClass, Bundle bundle, Scope... scopes) {
        Scope[] scopeArray = ArrayUtil.append(scopes, stageScope);
        Parent view = createView(viewClass, bundle, scopeArray);
        switchView(view);
    }

    @Override
    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> void addView(Pane parentPane, Class<ViewType> viewClass, Bundle bundle, Scope... scopes) {
        Scope[] scopeArray = ArrayUtil.append(scopes, stageScope);
        Parent view = createView(viewClass, bundle, scopeArray);
        addView(parentPane, view);
    }

    @Override
    public void launcherWindow(Stage targetWindow, Scene scene) {
        Pane sceneRootPane = WindowLauncher.getSceneRootPane(scene);
        if (sceneRootPane != null) {
            WindowUtils.addOnWindowCloseRequest(targetWindow, new EventPlusHandler.EventPlusHandlerListener() {
                @Override
                public boolean handle(WindowEvent event) {
                    if (!event.isConsumed()) {
                        if (WindowLauncher.ID_SCENE_ROOT_PANE.equals(scene.getRoot().getId())) {
                            sceneRootPane.getChildren().clear();
                        }
                        return true;
                    }
                    return false;
                }

                @Override
                public int getPriority() {
                    return Integer.MAX_VALUE;
                }
            });
        }
        applyStyle(scene);
        targetWindow.setScene(scene);
        targetWindow.show();
    }

}
